package com.it.stone_manage.service.Impl;

import com.it.stone_manage.dao.StoneRecordDao;
import com.it.stone_manage.model.SearchData;
import com.it.stone_manage.model.StoneRecord;
import com.it.stone_manage.model.StoneType;
import com.it.stone_manage.service.RecordService;
import com.it.stone_manage.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.sql.SQLException;
import java.util.*;

@Service
@Transactional
@Slf4j
public class RecordServiceImpl implements RecordService {
    @Autowired
    StoneRecordDao recordDao;

    private Result result = new Result();

    @Override
    public Map<String, Object> searchRecordData(SearchData searchData) {
//        获取一个月之前的时间
        Calendar c = Calendar.getInstance();
        c.set(Calendar.MONTH, c.get(Calendar.MONTH) - 1);
        //                默认查询流水记录
        searchData.setRecordType(searchData.getRecordType() != null ? searchData.getRecordType() : 2);
//                设置默认时间
        if (searchData.getStartDate() == null) {
            searchData.setStartDate(c.getTime());
        }
        if (searchData.getEndDate() == null) {
            searchData.setEndDate(new Date());
        }
        searchData.setCurrentPage((searchData.getCurrentPage() - 1) * searchData.getPageSize());
        Map<String, Object> result = new HashMap<>();
        result.put("data", recordDao.searchRecordData(searchData));
        result.put("total", recordDao.searchTotal(searchData));
        return result;
    }

    @Override
    public Result saveRecordData(StoneRecord stoneRecord) {
        try {
            if (stoneRecord.getId() != null) {
                recordDao.updateRecordData(stoneRecord);
                result.setStatus(true);
                result.setMessage("更新成功！");
            } else {
                StoneRecord record = recordDao.findRecord(stoneRecord);
                if (record == null) {
                    recordDao.saveRecordData(stoneRecord);
                    result.setStatus(true);
                    result.setMessage("保存成功");
                } else {
                    result.setStatus(false);
                    result.setMessage("内容已存在，请重新输入！");
                }

            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.setStatus(false);
            result.setMessage("系统错误，请稍后重试！");
        }
        return result;
    }

    @Override
    public Result deleteRecordData(StoneRecord stoneRecord) {
        try {
            stoneRecord.setRecordType(stoneRecord.getRecordType() != null ? stoneRecord.getRecordType() : 2);
            recordDao.deleteRecordData(stoneRecord);
            result.setStatus(true);
            result.setMessage("删除成功！");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.setStatus(false);
            result.setMessage("系统错误，请稍后再试！");
        }
        return result;
    }

    @Override
    public Result upload(MultipartFile uploadFile) {
        String filename = uploadFile.getOriginalFilename();
        Map<String, Object> resultMap;
        try {
            assert filename != null;
            if (filename.endsWith(".xls")) {
                resultMap = readXLS(uploadFile);
            } else {
                resultMap = readXLSX(uploadFile);
            }
            if (resultMap.get("dataList") != null) {
                List<StoneRecord> list = (List<StoneRecord>) resultMap.get("dataList");
                recordDao.saveBatchData(list);
                result.setStatus(true);
                result.setMessage("上传成功！");
            } else {
                result.setStatus(false);
                result.setMessage(resultMap.get("message").toString());
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            result.setStatus(false);
            result.setMessage("文件内容读取失败，请重试");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.setStatus(false);
            result.setMessage("插入数据库失败，请联系管理员");
        }
        return result;

    }

    @Override
    public void downloadTemplate(HttpServletResponse response) {

//        String templateName = "上传模板.xls";
//        response.reset();
//        response.setContentType("application/octet-stream");
//        response.setCharacterEncoding("UTF-8");
//        response.setHeader("Access-Control-Allow-Origin", "*");
//        response.setHeader("Access-Control-Expose-Headers", "*");
        // 文件名
//        response.setHeader("Content-Disposition", "attachment;filename=" + templateName);
//        response.setHeader("Pragma", "no-cache");


        InputStream in = null;
        OutputStream out = null;

        try {
            in = new FileInputStream(new File("src/main/java/com/it/stone_manage/fileTemplate/file.xls"));
            out = response.getOutputStream();
            byte[] b = new byte[200];
            int len;
            while ((len = in.read(b)) > 0) {
                response.getOutputStream().write(b, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != in) {
                try {
                    in.close();
                } catch (Exception e) {
                    in = null;
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                    out = null;
                }
            }
        }
    }

    public Map<String, Object> readXLS(MultipartFile file) throws IOException {
        Map<String, Object> result = new HashMap<>();

        List<StoneRecord> list = new ArrayList<>();
        InputStream inputStream = file.getInputStream();
        HSSFWorkbook workbook = new HSSFWorkbook(inputStream);
        //读取第一张sheet
        HSSFSheet sheet = workbook.getSheetAt(0);
//        数据是否正确
        boolean dataFlag = true;
//        错误信息
        StringBuilder errorMsg = new StringBuilder();
        //遍历每一行Excel获取内容
        for (int rowNum = 1; rowNum <= sheet.getLastRowNum(); rowNum++) {
            HSSFRow row = sheet.getRow(rowNum);
            if (row != null) {

                String storeHouse = row.getCell(0).getStringCellValue();
                String name = row.getCell(1).getStringCellValue();
                String standards = row.getCell(2).getStringCellValue();
                String gloss = row.getCell(3).getStringCellValue();
                String type = row.getCell(4).getStringCellValue();
                String recordType = row.getCell(5).getStringCellValue();
                row.getCell(6).setCellType(CellType.STRING);
                String record = row.getCell(6).getStringCellValue();
                Date recordTime = row.getCell(7).getDateCellValue();

                StoneRecord stoneRecord = new StoneRecord();
                stoneRecord.setStorehouse(storeHouse);
                stoneRecord.setName(name);
                stoneRecord.setStandards(standards);
                stoneRecord.setGloss(gloss);
                stoneRecord.setType(type);
                stoneRecord.setRecord(Integer.valueOf(record));
                if (recordType.equals("流水记录")) {
                    stoneRecord.setRecordType(2);
                } else if (recordType.equals("库存记录")) {
                    stoneRecord.setRecordType(3);
                } else {
                    errorMsg.append("第").append(rowNum).append("行,请正确输入记录种类！\n");
                }
                if (recordTime != null) {
                    stoneRecord.setDate(recordTime);

                } else {
                    errorMsg.append("第").append(rowNum).append("行,请正确输入时间！\n");

                }
//                检查是否为已存在的种类
                if (checkData(stoneRecord)) {
                    list.add(stoneRecord);
                } else {
                    dataFlag = false;
                    errorMsg.append("第").append(rowNum).append("行,请输入已存在的种类！\n");
                }
            }
        }
//        所有数据都没有错误则返回需要添加的数据列表
        if (dataFlag) {
            result.put("message", "上传成功！");
            result.put("dataList", list);

        } else {
            result.put("message", errorMsg);
        }
        return result;
    }

    //    检查数据是否合法
    public Boolean checkData(StoneRecord stoneRecord) {
        StoneType type = recordDao.checkData(stoneRecord);
        return type != null;
    }

    public Map<String, Object> readXLSX(MultipartFile file) throws IOException {
        Map<String, Object> result = new HashMap<>();
        ArrayList<StoneRecord> list = new ArrayList<>();

        InputStream inputStream = file.getInputStream();
        XSSFWorkbook Workbook = new XSSFWorkbook(inputStream);
//        数据是否正确
        boolean dataFlag = true;
//        错误信息
        StringBuilder errorMsg = new StringBuilder();

        XSSFSheet sheet = Workbook.getSheetAt(0);
        int lastRowNum = sheet.getLastRowNum();
        for (int rowNum = 1; rowNum <= lastRowNum; rowNum++) {
            XSSFRow row = sheet.getRow(rowNum);
            if (row != null) {
                String storeHouse = row.getCell(0).getStringCellValue();
                String name = row.getCell(1).getStringCellValue();
                String standards = row.getCell(2).getStringCellValue();
                String gloss = row.getCell(3).getStringCellValue();
                String type = row.getCell(4).getStringCellValue();
                String recordType = row.getCell(5).getStringCellValue();
                row.getCell(6).setCellType(CellType.STRING);
                String record = row.getCell(6).getStringCellValue();
                Date recordTime = row.getCell(7).getDateCellValue();

                StoneRecord stoneRecord = new StoneRecord();
                stoneRecord.setStorehouse(storeHouse);
                stoneRecord.setName(name);
                stoneRecord.setStandards(standards);
                stoneRecord.setGloss(gloss);
                stoneRecord.setType(type);
                stoneRecord.setRecord(Integer.valueOf(record));
                if (recordType.equals("流水记录")) {
                    stoneRecord.setRecordType(2);
                } else if (recordType.equals("库存记录")) {
                    stoneRecord.setRecordType(3);
                } else {
                    errorMsg.append("第").append(rowNum).append("行,请正确输入记录种类！\n");
                }
                if (recordTime != null) {
                    stoneRecord.setDate(recordTime);

                } else {
                    errorMsg.append("第").append(rowNum).append("行,请正确输入时间！\n");

                }
//                检查是否为已存在的种类
                if (checkData(stoneRecord)) {
                    list.add(stoneRecord);
                } else {
                    dataFlag = false;
                    errorMsg.append("第").append(rowNum).append("行,请输入已存在的种类！\n");
                }
            }
        }
//        所有数据都没有错误则返回需要添加的数据列表
        if (dataFlag) {
            result.put("message", "上传成功！");
            result.put("dataList", list);

        } else {
            result.put("message", errorMsg);
        }
        return result;
    }


}

